﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.Framework;
using Web.Framework.Svc;
using PlanProd.Contracts;
using WebAppPlanProduccion.Code.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using PlanProd.Contracts.Search;
using System.Web.Security;
using Web.Framework.Mapper;

namespace WebAppPlanProduccion.Code
{
    public abstract class BasePage : BaseWebPage
    {
        protected WebServiceHelper WebServiceHelper { get; set; }

        protected UIHelper UIHelper { get; set; }

        protected override void OnPreLoad(EventArgs e)
        {
            bool continueRequest = true;
            if (!DesignMode)
            {
                try
                {
                    WebServiceHelper = new WebServiceHelper();
                    WebServiceHelper.ServiceOptionsDefault = new ServiceOptions();
                    WebServiceHelper.ServiceOptionsDefault.UserName = BaseWebPage.UserName;
                    WebServiceHelper.ServiceOptionsDefault.CompanyId = BaseWebPage.CompanyId;
                    WebServiceHelper.ServiceOptionsDefault.ApplicationId = BaseWebPage.ApplicationId;

                    base.LoadOperations(WebServiceHelper.GetOperationsForUser(BaseWebPage.ApplicationId, BaseWebPage.CompanyId, BaseWebPage.UserName));

                    var securityContext = GetSecurityContextForDestinos();
                    WebServiceHelper.ServiceOptionsDefault.Operations = securityContext.Operations;
                    WebServiceHelper.ServiceOptionsDefault.IsAdmin = securityContext.IsAdmin;

                    UIHelper = new UIHelper();
                    UIHelper.companyId = BaseWebPage.CompanyId;
                    UIHelper.WebServiceHelper = WebServiceHelper;

                    base.LoadOperations(WebServiceHelper.GetOperationsForUser(BaseWebPage.ApplicationId, BaseWebPage.CompanyId, BaseWebPage.UserName));
                    //masterPage.PreLoad(new List<string>());
                }
                catch
                {
                    FormsAuthentication.RedirectToLoginPage();
                    continueRequest = false;
                }
            }

            if (continueRequest)
            {
                base.OnPreLoad(e);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Cargo los filtros
            if (!this.IsPostBack)
            {
                CargarValoresPreviosEnFiltros();
            }
        }

        protected bool EsPaginaQueRecurdaFiltros { get; set; }

        protected virtual void CargarValoresPreviosEnFiltros()
        {
            if (EsPaginaQueRecurdaFiltros)
            {
                // Hago una implementacion genérica, Todos estos controles son de filtro
                List<WebControl> webControls = GetFilterControls(this);
                if (webControls != null && webControls.Count > 0 && this.Session != null)
                {
                    // Obtengo de la session los valores para esta página
                    Dictionary<string, object> valuesFromSession = Session[this.GetType().ToString()] as Dictionary<string, object>;
                    if (valuesFromSession != null)
                    {
                        // Tengo los controles y los valores => los asigno
                        foreach (WebControl webCtrl in webControls)
                        {
                            if (valuesFromSession.ContainsKey(webCtrl.UniqueID))
                            {
                                object valor = valuesFromSession[webCtrl.UniqueID];
                                EntityMapper.SetValueToWebCtrl(webCtrl, valor);
                            }
                        }
                    }
                }
            }
        }

        protected virtual void RecordarFiltrosSeleccionados()
        {
            if (EsPaginaQueRecurdaFiltros)
            {
                // Hago una implementacion genérica, Todos estos controles son de filtro
                List<WebControl> webControls = GetFilterControls(this);
                if (webControls != null && webControls.Count > 0 && this.Session != null)
                {
                    // Obtengo de la session los valores para esta página
                    Dictionary<string, object> valuesFromSession = new Dictionary<string, object>();

                    // Tengo los controles y los valores => los asigno
                    foreach (WebControl webCtrl in webControls)
                    {
                        // Asignar el valor
                        valuesFromSession.Add(webCtrl.UniqueID, EntityMapper.GetValueFromWebControl(webCtrl));
                    }

                    Session[this.GetType().ToString()] = valuesFromSession;
                }
            }
        }

        public void LoadContextActions(List<LinkButton> linkButtons)
        {
            SiteMaster siteMaster = (SiteMaster)this.Master;
            siteMaster.LoadContextActions(linkButtons);
        }

        public SecurityContextForUser GetSecurityContext()
        {
            SecurityContextForUser securityContextForUser = new SecurityContextForUser();

            securityContextForUser.IsAdmin = BaseWebPage.IsAdmin;
            securityContextForUser.Operations = OperationsForUser;

            return securityContextForUser;
        }

        public SecurityContextForUser GetSecurityContextForDestinos()
        {
            SecurityContextForUser securityContext = new SecurityContextForUser();
            securityContext.IsAdmin = BaseWebPage.IsAdmin;
            List<string> operacionesFinales = new List<string>();
            List<int> entityIds = new List<int>();

            string userName = this.Page.User.Identity.Name;

            operacionesFinales = (List<string>)HttpContext.Current.Session[userName + "destinoOperation"];
            entityIds = (List<int>)HttpContext.Current.Session[userName + "destinoOperationEntity"];
            if (operacionesFinales == null || operacionesFinales.Count == 0)
            {
                WebServiceHelper.ServiceOptionsDefault.IsAdmin = true;
                List<Destino> destinoList = WebServiceHelper.GetDestinos(BaseWebPage.CompanyId, string.Empty);
                WebServiceHelper.ServiceOptionsDefault.IsAdmin = BaseWebPage.IsAdmin;

                List<Destino> operacionesEnDestino = destinoList.Where(d => !String.IsNullOrEmpty(d.SecurityKey)).ToList();
                securityContext.Total = operacionesEnDestino.Count;

                operacionesFinales = new List<string>();
                entityIds = new List<int>();
                // Otengo los destinos y las operaciones de los destinos
                foreach (var dest in operacionesEnDestino)
                {
                    if (securityContext.IsAdmin || OperationsForUser.Contains(dest.SecurityKey))
                    {
                        operacionesFinales.Add(dest.SecurityKey);
                        entityIds.Add(dest.Id);
                    }
                }

                HttpContext.Current.Session[userName + "destinoOperation"] = operacionesFinales;
                HttpContext.Current.Session[userName + "destinoOperationEntity"] = entityIds;
            }

            securityContext.Operations = operacionesFinales;
            securityContext.EntityId = entityIds;

            return securityContext;
        }

        public static void ClearReportingConfiguration(HttpApplicationState application)
        {
            string reportingConfigurationKey = "reportingConfigurationKey";
            application[reportingConfigurationKey] = null;
        }

        public static List<ReportingConfiguration> GetReportingConfiguration(HttpApplicationState application)
        {
            string reportingConfigurationKey = "reportingConfigurationKey";
            List<ReportingConfiguration> reportingConfigurationList;
            if (application[reportingConfigurationKey] == null)
            {
                WebServiceHelper wsHelper = new WebServiceHelper();
                reportingConfigurationList = wsHelper.GetReportingConfiguration(string.Empty);

                application[reportingConfigurationKey] = reportingConfigurationList;
            }
            else
            {
                reportingConfigurationList = (List<ReportingConfiguration>)application[reportingConfigurationKey];
            }

            return reportingConfigurationList;
        }

        public static List<ReporteGrupo> GetReporteGrupos(HttpApplicationState application)
        {
            string reporteGrupoKey = "reporteGrupoKey";
            List<ReporteGrupo> reporteGrupoList;
            if (application[reporteGrupoKey] == null)
            {
                WebServiceHelper wsHelper = new WebServiceHelper();
                reporteGrupoList = wsHelper.GetReporteGrupo(wsHelper.ServiceOptionsDefault, new SearchReport() { EmpresaId = BaseWebPage.CompanyId });

                application[reporteGrupoKey] = reporteGrupoList;
            }
            else
            {
                reporteGrupoList = (List<ReporteGrupo>)application[reporteGrupoKey];
            }

            return reporteGrupoList;
        }

        protected override void ApplySecurity()
        {
            base.ApplySecurity();

            LinkButton lnkGuardar = FindControlRecursive(this, "lnkGuardar") as LinkButton;
            SetJavascriptForToAvoidConfirmLeave(lnkGuardar);
            lnkGuardar = FindControlRecursive(this, "BoCommandGuardar") as LinkButton;
            SetJavascriptForToAvoidConfirmLeave(lnkGuardar);
        }

        protected static void SetJavascriptForToAvoidConfirmLeave(LinkButton lnkGuardar)
        {
            if (lnkGuardar != null)
            {
                if (String.IsNullOrEmpty(lnkGuardar.OnClientClick))
                {
                    lnkGuardar.OnClientClick = "window.AppCommonObj.Guardando = true; return true;";
                }
                else
                {
                    if (lnkGuardar.OnClientClick.Contains("return"))
                    {
                        lnkGuardar.OnClientClick = "  var fun = function(){" + lnkGuardar.OnClientClick + "}; if( fun() ) {window.AppCommonObj.Guardando = true; return true;} else {return false;}";
                    }
                    else
                    {
                        lnkGuardar.OnClientClick = " if( " + lnkGuardar.OnClientClick + " ) {window.AppCommonObj.Guardando = true; return true;} else {return false;}";
                    }
                }
            }
        }

        protected static bool IsFilterControl(WebControl control)
        {
            bool isFilter = false;

            if (control != null && control.HasAttributes)
            {
                string attr = control.Attributes["CampoFiltro"];
                isFilter = !String.IsNullOrEmpty(attr);
            }

            return isFilter;
        }

        protected List<WebControl> GetFilterControls(Control rootControl)
        {
            List<WebControl> controls = new List<WebControl>();

            Stack<Control> ctrlStack = new Stack<Control>();

            Control currentCtrl = rootControl;

            while (currentCtrl != null)
            {
                WebControl webCurrentCtrl = currentCtrl as WebControl;
                if (webCurrentCtrl != null)
                {
                    if (IsFilterControl(webCurrentCtrl))
                    {
                        controls.Add(webCurrentCtrl);
                    }
                }

                if (currentCtrl.Controls.Count > 0)
                {
                    foreach (Control ctrl in currentCtrl.Controls)
                    {
                        ctrlStack.Push(ctrl);
                    }
                }

                if (ctrlStack.Count > 0)
                {
                    currentCtrl = ctrlStack.Pop();
                }
                else
                {
                    currentCtrl = null;
                }
            }

            return controls;
        }
    }
}